package de.haw;

import de.haw.util.Range;

public class Porsche911GT2RS {
    
      private static final double KILO = 1000.0;
      private static final double HOUR_IN_S = 3600.0;
      
      private static final double KMH_IN_MS = HOUR_IN_S / KILO;
	// Gewicht in KG
	private static final double mass = 1445;
	// Leistung in W
	private static final double powerPropMax = 456*KILO;
	// Maximalgeschwindigkeit in m/s
	private static final double speedMax = 330/KMH_IN_MS;
	// Erdanziehungskraft von 1g (
	private static final double accEarth = 9.81;
	// maximale Beschleunigungskraft N(kgms-2)
	private static final double forcePropMax = mass * accEarth;
	private static double dragConst;

	private double forcePropAbs;
	private double powerProp;
	private double time;
	private double pos;
	private double speed;
	private double level;
	private double forceProp;
	private double forceDrag;
	private double force;
	private double acc;
	
	public Porsche911GT2RS() {
		dragConst = Math.abs(powerPropMax / (speedMax * speedMax * speedMax));
		reset();
	}

	public void set(double time, double pos, double speed, double level) {
		this.time = time;
		this.pos = pos;
		this.speed = speed;
		this.level = level;
	}
	
	public void reset() {
		set(0.0, 0.0, 0.0, 0.0);
	}
	
	public void step(double deltaTime, double level) {
            Range.checkRange(-1.0, 1.0, level);
            
            powerProp = Math.abs(this.level) * powerPropMax;
            forcePropAbs = Math.min(forcePropMax, powerProp / (Math.max(Math.abs(speed), 0.000001)));
            forceProp = forcePropAbs * Math.signum(this.level);
            
            forceDrag = dragConst * (speed * speed) * Math.signum(-speed);
            
            force = forceProp + forceDrag;
            
            acc = force / mass;
            
            this.level = level;
            this.speed += (acc * deltaTime); 
            this.pos += (speed * deltaTime);
            
            this.time += deltaTime;
	}
	
	public double getAcc() {
		return acc;
	}
	
	public double getForcePropAbs() {
		return forcePropAbs;
	}
	
	public double getForceProp() {
		return forceProp;
	}
	
	public double getDragConst() {
		return dragConst;
	}
	
	public double getForce() {
		return force;
	}
	
	public double getTime() {
		return time;
	}
	
	public double getPos() {
		return pos;
	}
	
	
        public double getSpeed() {
		return speed;
	}
        
        public double getSpeedInKmh() {
		return speed * KMH_IN_MS;
        }
}
